//
//  ViewController.m
//  Socket
//
//  Created by admin on 2019/10/5.
//  Copyright © 2019 admin. All rights reserved.
//

#import "ViewController.h"
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    //1. 创建Socket
        /*
         （1）af：一个地址描述。目前仅支持AF_INET格式，也就是说ARPA Internet地址格式。 即指定，IPv4

         （2）type：指定socket类型。新套接口的类型描述类型，如TCP（SOCK_STREAM）和UDP（SOCK_DGRAM）。
         常用的socket类型有，SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等。
         
         （3）protocol：顾名思义，就是指定协议。套接口所用的协议。如调用者不想指定，可用0。
         常用的协议有，IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等，
         它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
         */
    
    //返回值 如果创建成功返回Socket的描述符，失败-1
    int clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    
    //2. 连接服务器

        /*
         （1）int connect(int sockfd, struct sockaddr * serv_addr, int addrlen);
         （2）sockfd：标识一个套接字。 - socket的描述符
         （3）serv_addr：结构体 - 套接字s想要连接的主机地址和端口号。
         （4）addrlen：结构体的长度 - name缓冲区的长度。 sizeof
         */

    
    //返回值 成功0 失败非0
    
    /*
     失败的原因，是12345端口没有被使用。
     连接服务器- 打开Netcat，模拟服务器。
        打开终端>_
            nc -lk 12345
        nc -> Netcat 终端下用于调试和检查网络的工具
     */
    
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    //计算机存储数字的时候，存储的方式不一样，但是网络都是使用大尾顺序，使用htons可以根据计算机转换保证为大尾顺序
    //大尾顺序 - 地址的低位存储值的高位，小尾顺序 - 地址的低位存储值的低位。
    addr.sin_port = htons(12345);
    
    int result = connect(clientSocket, (const struct sockaddr *) &addr, sizeof(addr));
    if (result != 0)
    {
        NSLog(@"失败");
        return;
    }
    
    //3.向服务器发送数据
        /*
         （1）第一个参数指定发送端套接字描述符；
         （2）第二个参数指明一个存放应用程序要发送数据的缓冲区；
         （3）第三个参数指明实际要发送的数据的字节数；
         （4）第四个参数一般置0。
         */
    
    //返回值 成功返回发送的字符数，失败-1
    const char *msg = "Hello world";
    ssize_t sendCount = send(clientSocket, msg, strlen(msg), 0);
    NSLog(@"发送的字符数 %zd",sendCount);
    
    
    //4. 接收服务器发送的消息
    //返回的是实际的字节个数
    uint8_t buffer[1024];
    ssize_t recvCount = recv(clientSocket, buffer, sizeof(buffer), 0);
    NSLog(@"接收的字节数 %zd",recvCount);
    
    //把字节数组转换为字符串
    NSData *data = [NSData dataWithBytes:buffer length:recvCount];
    NSString *recvMessage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"收到信息：%@",recvMessage);
    
    //5. 关闭连接
    close(clientSocket);
}



@end
